﻿/*
 * mdc.h
 *
 *  Created on: 2020年5月3日
 *      Author: root
 */

#ifndef SRC_MDC_H_
#define SRC_MDC_H_
//---------------------------------------------------------------------------

#include <vector>
#include "datatype.h"
#include "common.h"
#include "thread.h"
//---------------------------------------------------------------------------

#define MAX_CHL_CNT	16				//通道最大个数 目前只支持最多16通道
#define MAX_CHL_NZN	4				//每通道最大枪数 单通道最多支持4把枪
//---------------------------------------------------------------------------

#pragma pack(push, 1)

typedef struct tagSerialParam		//串口配置信息
{
	uint32	BaudRate;				//波特率
	BYTE	ByteSize;				//数据位(范围：[5,8]，分别表示5-8个数据位)
	BYTE	Parity;					//奇偶校验位(范围：0-无校验，1-奇校验，2-偶校验)
	BYTE	StopBits;				//停止位(范围：[1,3]，分别表示1,1.5,2个停止位)
} TSERIALPARAM;

//油枪配置信息
typedef struct tagNZN
{
	BYTE	GunCode;					//枪号
	uint16	OilCode;					//油品
} TNZN;

//通道油机配置信息
typedef struct tagChannelInfo
{
	BYTE		ChannelNo;				//通道号 1~MAX_CHL_CNT
	BYTE		Protocol;				//协议编号: 0:无效,油机协议编号范围[1,191]
	TSERIALPARAM Param;					//对应油机的串口通讯参数
	BYTE		AutoAuthorize;			//1/0:是/否自动授权
	BYTE		Pump_Log;				//1/0:是/否记油机日志
	BYTE		NZN_Count;				//枪数 <= MAX_CHL_NZN
	TNZN		Guns[MAX_CHL_NZN];

	void Init() { memset(this, 0, sizeof(tagChannelInfo)); }
} TCHLINFO;

//集线器油机配置信息
typedef struct tagFCC_CFG
{
	uint32	IP;							//FCC IP
	uint16	Port;						//FCC端口
	BYTE	PC_Log;						//1/0:是/否记PC日志
	BYTE	Count;						//FCC通道数<= MAX_CHL_CNT
	TCHLINFO Chls[MAX_CHL_CNT];			//FCC通道详情

	void Init() { memset(this, 0, sizeof(tagFCC_CFG)); }
} TMDC_CFG;

typedef struct tagOilData
{
	uint16	OilCode;					//油品编号：采用中石化标准油品代码（见附录）
	uint16	Price;						//油品单价（分）
	uint16	Density;					//密度（g/ml）

	void init() { OilCode = 0; Price = 0; Density = 0; }
} TOILDATA;

typedef struct tagNzlOilData
{
	BYTE	ChlNo;						//通道号
	BYTE	NZL;						//枪号
	TOILDATA Oil1;						//原油品信息（从枪上读取）
	TOILDATA Oil2;						//新油品信息（上层设置）

	void init() { memset(this, 0, sizeof(tagNzlOilData)); }
} TNZLOILDATA;

#pragma pack(pop)

//---------------------------------------------------------------------------

typedef std::vector<TFRAMEBIN *> TSNDCMDLST;

class TClientSocket;
class TSendThread;
class TRecvThread;

class TMDC
{
private:
	int		MDCNo;					//MDC编号
	bool	Working;				//是否工作中
	char	IP[20];					//MDC启动监听的IP
	uint16	Port;					//MDC监听的端口

	TSNDCMDLST CmdLst;				//向MDC发送的命令队列
	TClientSocket * CltSock;		//客户端socket对象
	TSendThread * SndThread;
	TRecvThread * RcvThread;
	TMDC_CFG	MDC_CFG;

	friend class TClientSocket;
	friend class TSendThread;
	friend class TRecvThread;

	void FreeCmdLst();
	void GetConfigInfo();
	void GetNzlPrc(BYTE chl, BYTE nzl);
	void SetNzlPrc(BYTE chl, BYTE nzl, uint16 prc);
	void GetNzlsPrc();
	void UpCFG(BYTE chn, BYTE nzl, uint16 OilCode);

	TNZLOILINFO GetNZLInfoFromCFG(BYTE chn, BYTE nzl);
protected:
	void SendCmd(TFRAMEBIN *pfrm);
	void ReadFrame();
	void ProcessFrame(TFRAMEBIN *pfrm);

	void QryDevInfo();
	void QryMDCTime();
	void SetMDCTime(TDATETIME *pdt);
	void QryNzlPrc(TNZLADDR *pDat);
	void QryNZLOilInfo(TNZLADDR *pDat);
	void SetNZLOilInfo(TNZLOILINFO *pDat);
	void QryVTOT(TNZLADDR *pDat);
	void QryTTC(TMDCTTC *pDat);

	void GetMaxTTC(BYTE *pData, uint32 uSize);
	void SetAuthCfg(BYTE *pData, uint32 uSize);
	void GetAuthCfg();
	void GunAuth(BYTE *pData, uint32 uSize);
	void GunCancelAuth(BYTE *pData, uint32 uSize);

	void UL_MDCCFG(BYTE *pData);
	void UL_DevInfo(BYTE *pData);
	void UL_MDCTime(BYTE *pData);
	void UL_Transaction(BYTE *pData);
	void UL_NoTTC(BYTE *pData);
	void UL_PumpState(BYTE *pData);
	void UL_VTOT(BYTE *pData);
	void UL_PumpPRC(BYTE *pData);
	void UL_ChlMaxTTC(BYTE *pData);

	void UL_QryAuth(BYTE *pData);
	void UL_AuthRet(BYTE *pData);
	void UL_CancelAuthRet(BYTE *pData);
	void UL_QryAuthCfg(BYTE *pData);
public:
	TMDC(int ANo);
	~TMDC();

	TErrorCallback ErrCallback;
	TOnNotifyEvent NotifyEvent;

	int GetMDCNo();
	int Init(char *pzIPv4, uint16 uPort);
	int Connect();
	int StartWork();
	int StopWork();
	int DoCommand(int cmd, BYTE *pData, uint32 uSize);
};
//---------------------------------------------------------------------------

class TClientSocket
{
private:
	int	FSocket;							//socket
	TMDC *MDC;

	int ReadByte(char *ch);
public:
	TClientSocket(TMDC *pMDC);
	~TClientSocket();

	int SendTimeout;
	int RecvTimeout;

	int CreateSocket();
	int ConnectTo(char *pzIP, uint16 port);
	void CloseSocket();

	int SendBuffer(char *pBuffer, int iSize);
	int RecvBuffer(char *pBuffer, int iSize);
};
//---------------------------------------------------------------------------

class TSendThread : public TThread
{
private:
	TMDC *MDC;
protected:
	void Execute();
public:
	TSendThread(TMDC *pMdc);

	bool IsOver;
};
//---------------------------------------------------------------------------

class TRecvThread : public TThread
{
private:
	TMDC *MDC;
protected:
	void Execute();
public:
	TRecvThread(TMDC *pMdc);

	bool IsOver;
};
//---------------------------------------------------------------------------

#endif /* SRC_MDC_H_ */
